﻿using System.Linq;
using ExtendedMvc.Tests.Model;
using ExtendedMvc.Tests.Model.Entities;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ExtendedMvc.Tests {


	/// <summary>
	///This is a test class for TextBoxTest and is intended
	///to contain all TextBoxTest Unit Tests
	///</summary>
	[TestClass()]
	public class TextBoxTest {

		private static DummyDataSource database;
		private static ModelViewPage<Dummy> view;
		private static ModelViewForm<Dummy> form;

		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		public TestContext TestContext { get; set; }

		#region Additional test attributes
		// 
		//You can use the following additional attributes as you write your tests:
		//
		//Use ClassInitialize to run code before running the first test in the class
		[ClassInitialize()]
		public static void MyClassInitialize(TestContext testContext) {
			database = new DummyDataSource();
			var dummy = database.Dummies.All().First();
			view = MvcMockHelpers.FakeViewPage("Index", dummy);
			form = new ModelViewForm<Dummy>(view.Html);
		}

		//Use ClassCleanup to run code after all tests in a class have run
		//[ClassCleanup()]
		//public static void MyClassCleanup() {
		//}
		//
		//Use TestInitialize to run code before running each test
		[TestInitialize()]
		public void MyTestInitialize() {
			view.ViewContext.ViewData.ModelState.Clear();
		}

		//Use TestCleanup to run code after each test has run
		//[TestCleanup()]
		//public void MyTestCleanup() {
		//}
		//
		#endregion

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithPropertyName() {
			// Arrange
			var name = "BasicProperty";
			var dummy = database.Dummies.All().First();
			var expectedOutput = string.Format(@"<input id=""{1}"" name=""{1}"" type=""text"" value=""{0}"" />", dummy.BasicProperty, name);

			// Act
			var textBox = form.TextBox(name);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_ForModel() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var expectedOutput = string.Format(@"<input id=""{1}"" name=""{1}"" type=""text"" value=""{0}"" />", expectedValue, expectedName);

			// Act
			var textBox = form.TextBox(m => m.BasicProperty);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_ForRequiredField() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.RequiredProperty;
			var expectedName = "RequiredProperty";
			var expectedOutput = string.Format(@"<input id=""{1}"" name=""{1}"" required=""required"" type=""text"" value=""{0}"" />", expectedValue, expectedName);

			// Act
			var textBox = form.TextBox(m => m.RequiredProperty);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithRequired() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var expectedOutput = string.Format(@"<input id=""{1}"" name=""{1}"" required=""required"" type=""text"" value=""{0}"" />", expectedValue, expectedName);

			// Act
			var textBox = form.TextBox(m => m.BasicProperty).Required();
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithDisabled() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var expectedOutput = string.Format(@"<input disabled=""disabled"" id=""{1}"" name=""{1}"" type=""text"" value=""{0}"" />", expectedValue, expectedName);

			// Act
			var textBox = form.TextBox(m => m.BasicProperty).Disabled();
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_ForRequiredField_WithValidationError() {
			// Arrange
			view.ViewContext.ViewData.ModelState.AddModelError("RequiredProperty", "Field is required.");
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.RequiredProperty;
			var expectedName = "RequiredProperty";
			var expectedOutput = string.Format(@"<input class=""input-validation-error"" id=""{1}"" name=""{1}"" required=""required"" type=""text"" value=""{0}"" />", expectedValue, expectedName);

			// Act
			var textBox = form.TextBox(m => m.RequiredProperty);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_ForRequiredField_WithValidationMessage() {
			// Arrange
			var errrorMessage = "Field is required.";
			view.ViewContext.ViewData.ModelState.AddModelError("RequiredProperty", errrorMessage);
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.RequiredProperty;
			var expectedName = "RequiredProperty";
			var expectedOutput = string.Format(@"<input class=""input-validation-error"" id=""{1}"" name=""{1}"" required=""required"" type=""text"" value=""{0}"" /><span class=""field-validation-error"" id=""RequiredProperty_Error"">{2}</span>", expectedValue, expectedName, errrorMessage);

			// Act
			var textBox = form.TextBox(m => m.RequiredProperty).AddValidationMessage();
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithMaxLength() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.SizedProperty;
			var expectedName = "SizedProperty";
			var expectedOutput = string.Format(@"<input id=""{1}"" maxlength=""240"" name=""{1}"" type=""text"" value=""{0}"" />", expectedValue, expectedName);

			// Act
			var textBox = form.TextBox(m => m.SizedProperty).MaxLength(240);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithSize() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.SizedProperty;
			var expectedName = "SizedProperty";
			var expectedOutput = string.Format(@"<input id=""{1}"" name=""{1}"" size=""240"" type=""text"" value=""{0}"" />", expectedValue, expectedName);

			// Act
			var textBox = form.TextBox(m => m.SizedProperty).Size(240);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithChange() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var onChangeEvent = "return false;";
			var expectedOutput = string.Format(@"<input id=""{0}"" name=""{0}"" onchange=""{2}"" type=""text"" value=""{1}"" />", expectedName, expectedValue, onChangeEvent);

			// Act
			var textBox = form.TextBox(m => m.BasicProperty).OnChange(onChangeEvent);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithClick() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var onClickEvent = "return false;";
			var expectedOutput = string.Format(@"<input id=""{0}"" name=""{0}"" onclick=""{2}"" type=""text"" value=""{1}"" />", expectedName, expectedValue, onClickEvent);

			// Act
			var textBox = form.TextBox(m => m.BasicProperty).OnClick(onClickEvent);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithFocus() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var onFocusEvent = "return false;";
			var expectedOutput = string.Format(@"<input id=""{0}"" name=""{0}"" onfocus=""{2}"" type=""text"" value=""{1}"" />", expectedName, expectedValue, onFocusEvent);

			// Act
			var textBox = form.TextBox(m => m.BasicProperty).OnFocus(onFocusEvent);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithBlur() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var onBlurEvent = "return false;";
			var expectedOutput = string.Format(@"<input id=""{0}"" name=""{0}"" onblur=""{2}"" type=""text"" value=""{1}"" />", expectedName, expectedValue, onBlurEvent);

			// Act
			var textBox = form.TextBox(m => m.BasicProperty).OnBlur(onBlurEvent);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithMouseOut() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var onMouseOutEvent = "return false;";
			var expectedOutput = string.Format(@"<input id=""{0}"" name=""{0}"" onmouseout=""{2}"" type=""text"" value=""{1}"" />", expectedName, expectedValue, onMouseOutEvent);

			// Act
			var textBox = form.TextBox(m => m.BasicProperty).OnMouseOut(onMouseOutEvent);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithMouseOver() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var onMouseOverEvent = "return false;";
			var expectedOutput = string.Format(@"<input id=""{0}"" name=""{0}"" onmouseover=""{2}"" type=""text"" value=""{1}"" />", expectedName, expectedValue, onMouseOverEvent);

			// Act
			var textBox = form.TextBox(m => m.BasicProperty).OnMouseOver(onMouseOverEvent);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for TextBox Constructor
		///</summary>
		[TestMethod()]
		public void TextBox_WithKeyPress() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var onKeyPressEvent = "return false;";
			var expectedOutput = string.Format(@"<input id=""{0}"" name=""{0}"" onkeypress=""{2}"" type=""text"" value=""{1}"" />", expectedName, expectedValue, onKeyPressEvent);

			// Act
			var textBox = form.TextBox(m => m.BasicProperty).OnKeyPress(onKeyPressEvent);
			var output = textBox.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}
	}
}
